#include <iostream>
#include <memory>
using namespace std;

/*
lambda 函数式编程

捕获， 将外部变量的值复制到lambda内部，内部的值是外部变量的副本，不会影响原变量

[capture](parameters) mutable -> return_type { 
    // 函数体 
}
捕获列表 [ ]：定义从外部作用域捕获的变量
[=] 值捕获所有外部变量
[&] 引用捕获所有外部变量      捕获引用会修改外部变量的值
[x] 只值捕获x
[&y] 只引用捕获y
参数列表 ( )：和普通函数参数类似
返回类型 ->（可省略，编译器会自动推导）
函数体 { }：包含要执行的代码

auto greet = [] { std::cout << "Hello Lambda!"; };
greet();  // 输出：Hello Lambda!

auto sum = [](int a, int b) { return a + b; };
cout << sum(3, 4); // 输出7

带捕获的lambda：
int multiplier = 3;
auto times = [multiplier](int x) { return x * multiplier; };
cout << times(5); // 输出15

在STL算法中使用：
vector<int> v = {1,2,3,4};
sort(v.begin(), v.end(), [](int a, int b) {
    return a > b; // 降序排序
});
*/


class MyClass{
    int a;
    int b;
public:
    MyClass(int a, int b):a(a),b(b){}
    int getA(){
        return a;
    }
    auto mylambda(){
        return [this](){
            this->a=5;
        };
    }
    void print(){
        auto t = [=](){             //按值捕获所有外部变量
            cout<<"a="<<a<<endl;
            cout<<"b="<<b<<endl;
        };
        t();
    }

};
int main()
{
    // 按值捕获，不会影响外部变量
    int a = 10;
    auto value_capture = [a] {
        return a*2;
    };
    a = 100;
    cout<<value_capture()<<endl;    

    // 按引用捕获，会改变外部变量的值
    int b = 10;
    auto chang = [&b]() {
        b = 100;
    };
    chang();
    cout<<b<<endl;

    //按移动捕获，将外部变量移动到lambda内部
    unique_ptr<int> p = make_unique<int>(10);
    auto move_capture = [p = move(p)]() {
        cout<<*p<<endl;
    };
    move_capture();

    //捕获this指针，修改阶成员函数
    MyClass myclass(9, 10);
    auto mylambda = myclass.mylambda();   //lambda单独生命是函数指针得赋值运行不然只是个指针
    mylambda();
    cout<<myclass.getA()<<endl;
    myclass.print();
}
